package org.dromara.system.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserExportVo;
import org.dromara.system.domain.vo.SysUserVo;

import java.util.List;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：用户表 数据层
 */
public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {

    /**
     * 查询用户列表（分页）
     * 使用@DataPermission注解来限制和说明数据权限，确保用户只能查询自己有权限查看的数据
     * 在此注解中，通过@DataColumn元素指定了列的映射关系，确保查询条件能够正确应用到数据库字段
     * 具体来说，"deptName"和"userName"字段分别映射到"u.dept_id"和"u.user_id"，以便在跨表查询时正确应用权限限制
     *
     *
     * @param page 分页对象，用于接收分页参数
     * @param queryWrapper 查询条件封装对象，用于动态查询
     * @return 返回分页的用户视图列表
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "u.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);

    /**
     * 根据部门名称和用户名称筛选条件，查询用户列表
     *
     * @param queryWrapper 查询条件封装类，用于指定查询的条件，如部门名称、用户名称等
     * @return 返回查询到的用户列表，列表中的每个元素为SysUserVo类型，代表一个用户的信息
     *
     * 使用@DataPermission注解来限制查询权限，确保用户只能查询到有权限访问的数据
     * 注解中定义了两个列权限条件：
     * 1. @DataColumn(key = "deptName", value = "dept_id")：表示查询条件中的部门名称对应数据库中的dept_id字段
     * 2. @DataColumn(key = "userName", value = "user_id")：表示查询条件中的用户名称对应数据库中的user_id字段
     * 这样做是为了在查询时能够正确地映射字段，同时保证查询的合法性
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "dept_id"),
        @DataColumn(key = "userName", value = "user_id")
    })
    List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);

    /**
     * 根据条件分页查询用户列表
     *
     * @param queryWrapper 查询条件
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    List<SysUserExportVo> selectUserExportList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);

    /**
     * 根据条件分页查询已配用户角色列表
     *
     * @param queryWrapper 查询条件
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    Page<SysUserVo> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param queryWrapper 查询条件
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);

    /**
     * 计算特定用户ID关联的用户数量
     *
     * @param userId 用户ID，用于过滤数据
     * @return 关联的用户数量
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "dept_id"),
        @DataColumn(key = "userName", value = "user_id")
    })
    long countUserById(Long userId);

    /**
     * 更新用户信息
     * 此方法通过@param中定义的参数来指定更新操作的数据权限
     * 具体来说，它允许更新与特定部门ID（dept_id）关联的部门名称（deptName），
     * 以及与特定用户ID（user_id）关联的用户名（userName）
     * 这对于确保只有适当的用户可以更新他们有权访问的数据至关重要
     *
     * @param user 实例对象，包含要更新的用户信息
     * @param updateWrapper 查询条件封装器，用于指定更新操作的条件
     * @return 更新操作受影响的行数
     */
    @Override
    @DataPermission({
        @DataColumn(key = "deptName", value = "dept_id"),
        @DataColumn(key = "userName", value = "user_id")
    })
    int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper);

    /**
     * 根据ID更新SysUser实体的信息
     * 该方法通过覆盖基类的方法来实现更新功能，并且在更新前会对数据权限进行验证
     * 主要用于确保当前用户有权限更新指定的用户信息
     *
     * @param user 待更新的SysUser对象，包含要更新的信息
     * @return 更新操作影响的行数
     */
    @Override
    @DataPermission({
        @DataColumn(key = "deptName", value = "dept_id"),
        @DataColumn(key = "userName", value = "user_id")
    })
    int updateById(@Param(Constants.ENTITY) SysUser user);

}
